package com.qujia.station.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.qujia.common.constant.Constants;
import com.qujia.common.core.domain.ResultData;
import com.qujia.common.core.domain.entity.SysUser;
import com.qujia.common.exception.CustomException;
import com.qujia.coupon.domain.cancel.*;
import com.qujia.coupon.mapper.CouponWriteOffRecordsMapper;
import com.qujia.coupon.service.ICouponInfoService;
import com.qujia.integral.domain.IntegralOrder;
import com.qujia.integral.service.IIntegralOrderService;
import com.qujia.station.config.MqttConfig;
import com.qujia.station.constant.ApiConst;
import com.qujia.station.domain.Oil;
import com.qujia.station.domain.PointsMerchandiseWriteOffRecord;
import com.qujia.station.domain.Station;
import com.qujia.station.domain.StationDeviceManage;
import com.qujia.station.domain.dto.EquipmentMessageDTO;
import com.qujia.station.mapper.StationDeviceManageMapper;
import com.qujia.station.service.CancelCouponService;
import com.qujia.station.service.IOilService;
import com.qujia.station.service.IStationService;
import com.qujia.station.service.PointsMerchandiseWriteOffRecordService;
import com.qujia.system.service.ISysUserService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Auther: zxy
 * @Date: 2023/10/18 10:42
 * @Description:
 */
@Service
@Slf4j
public class CancelCouponServiceImpl implements CancelCouponService
{

    @Autowired
    private ICouponInfoService couponInfoService;

    @Autowired
    private ISysUserService iSysUserService;
    @Autowired
    private IOilService oilService;
    @Autowired
    private IStationService iStationService;

    @Resource
    private CouponWriteOffRecordsMapper couponWriteOffRecordsMapper;

    @Resource
    private IIntegralOrderService integralOrderService;

    @Resource
    private PointsMerchandiseWriteOffRecordService pointsMerchandiseWriteOffRecordService;

    @Autowired
    private MqttConfig providerClient;

    @Resource
    private StationDeviceManageMapper stationDeviceManageMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    @SneakyThrows
    @Transactional
    public ResultData<CouponInfoVO> cancelCoupon(CancelCouponDto cancelCouponDto) {

        //根据券码获取优惠券信息
        log.info("核销码：{}", cancelCouponDto.getCouponNo());
        String couponNo = cancelCouponDto.getCouponNo();
        String[] prefix = couponNo.split("_");
        String prefix1 = prefix[0];
        if (prefix1.equals("sp")){
            //获取积分订单信息
            IntegralOrder integralOrder = new IntegralOrder();
            integralOrder.setIntegralOrderNo(prefix[1]);
            List<IntegralOrder> integralOrders = integralOrderService.selectIntegralOrderList(integralOrder);

            //获取核销人员信息
            SysUser sysUser = iSysUserService.selectUserById(Long.valueOf(cancelCouponDto.getOilPersonnelId()));

            if (CollectionUtil.isNotEmpty(integralOrders) && ObjectUtils.isNotEmpty(sysUser)) {
                IntegralOrder integralOrder1 = integralOrders.get(0);
                if (integralOrder1.getWriteOffStatus().equals(1)){
                    return ResultData.error("该商品已核销");
                }
                //核销积分订单
                Integer i = cancelGoods(integralOrder1, sysUser, cancelCouponDto);
                if (i == 1){
                    Date cancelGoods = pointsMerchandiseWriteOffRecordService.getCancelGoods(integralOrder1.getIntegralOrderNo());
                    if (null != cancelGoods) {
                        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        String format = sdf1.format(cancelGoods);
                        CouponInfoVO couponInfoVO = CouponInfoVO.builder().
                                writeOffTime(format)
                                .isNotGoods(1)
                                .build();

                        return ResultData.success(couponInfoVO);
                    }
                }
                return ResultData.error("核销失败！");
            }

            return ResultData.error("无此订单！");
        }

        if (prefix1.equals("xcq")){
            //去到核销码前缀
            cancelCouponDto.setCouponNo(prefix[1]);
            List<CancelCouponUser> couponUsersInfo = couponInfoService.selectUserAllCoupons(CancelCouponUser.builder().couponNo(cancelCouponDto.getCouponNo()).build());
            //获取核销人员信息
            SysUser sysUser = iSysUserService.selectUserById(Long.valueOf(cancelCouponDto.getOilPersonnelId()));

            if (CollectionUtil.isNotEmpty(couponUsersInfo) && ObjectUtils.isNotEmpty(sysUser)) {
                CancelCouponUser couponUser = couponUsersInfo.get(0);
                Integer i = cancelCouponType(couponUser, sysUser, cancelCouponDto);
                if (i == 1){
                    String couponType = couponUser.getCancelCouponTemplateInfo().getCouponType();
                    String couponEffectiveTime = couponUser.getCouponEffectiveTime();
                    String oils = couponUser.getOils();
                    String couponStaNames = couponUser.getCouponStaNames();
                    Date cancelCouponTime = couponWriteOffRecordsMapper.getCancelCouponTime(cancelCouponDto.getCouponNo());
                    String writeOffTime = null;
                    String couponIsUsed = null;
                    String couponRemark = couponUser.getCancelCouponTemplateInfo().getCouponRemark();
                    BigDecimal couponAmt = couponUser.getCancelCouponTemplateInfo().getCouponAmt();
                    if (null != cancelCouponTime){
                        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        writeOffTime = sdf1.format(cancelCouponTime);
                        couponIsUsed = "1";
                    }
                    CouponInfoVO couponInfoVO = CouponInfoVO.builder().
                            couponEffectiveTime(couponEffectiveTime).
                            couponType(couponType).
                            couponStaNames(couponStaNames).
                            oils(oils).
                            writeOffTime(writeOffTime).
                            couponIsUsed(couponIsUsed).
                            couponRemark(couponRemark).
                            amt(String.valueOf(couponAmt)).build();

                    return ResultData.success(couponInfoVO);
                }
                return ResultData.error("核销失败！");
            }

            return ResultData.error("无此优惠券！");
        }
        return ResultData.error("核销失败,请传入正确核销码！");
    }

    //根据优惠券类型进行核销
    private Integer cancelCouponType(CancelCouponUser couponUser, SysUser sysUser, CancelCouponDto ccd) throws Exception {
        switch (couponUser.getCancelCouponTemplateInfo().getCouponType()) {
            //现金券
            case "1":
                return checkCoupon(couponUser,sysUser,ccd);
            //折扣券
            case "2":
                return checkCoupon(couponUser,sysUser,ccd);
            //兑换券
            case "3":
                if ("1".equals(sysUser.getEnterpriseId())) {
                    if ("0".equals(sysUser.getStatus())) {
                        //获取该兑换券的核销站点
                        List<CancelCouponUser> couponUsersInfo = couponInfoService.selectUserAllCoupons(CancelCouponUser.builder().couponNo(ccd.getCouponNo()).build());

                        if (CollectionUtil.isNotEmpty(couponUsersInfo)) {
                            if (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(couponUsersInfo.get(0).getCouponEffectiveTime()).after(new Date())) {
                                if ("0".equals(couponUsersInfo.get(0).getCouponIsUsed())) {
                                    CancelCouponTemplate couponTemplateInfo = couponUsersInfo.get(0).getCancelCouponTemplateInfo();
                                    if (null != couponTemplateInfo && "3".equals(couponTemplateInfo.getCouponType())) {
                                        if ("1".equals(couponTemplateInfo.getCouponTemplateStatus())) {
                                            boolean boo = false;
                                            if (StringUtils.isNotBlank(couponTemplateInfo.getVerification())) {
                                                if (Arrays.asList(couponTemplateInfo.getVerification().split(",")).contains(sysUser.getStationId()))
                                                    boo = true;
                                            }
                                            if (sysUser.getEnterpriseId().equals(couponUsersInfo.get(0).getEnterpriseId().toString()))
                                                boo = true;
                                            if (boo) {
                                                //更新用户优惠券信息
                                                int i = couponInfoService.updateCouponUser(CancelCouponUser.builder().couponNo(ccd.getCouponNo()).verificationTime(new Date()).couponIsUsed("1").verificationUserAccount(sysUser.getUserName()).verificationUserPhone(sysUser.getPhonenumber()).build());
                                                //更新优惠券使用模板数量
                                                int i1 = couponInfoService.updateCouponTemplate(CancelCouponTemplate.builder().couponTemplateId(couponTemplateInfo.getCouponTemplateId()).useCouponNum(couponTemplateInfo.getUseCouponNum() + 1).build());
                                                Integer i2 = addCancelCouponRecord(couponUser, ccd);
                                                if (i != 1 || i1 != 1 || i2 != 1) {
                                                    log.error("更新用户优惠券信息:{},更新优惠券使用模板数量:{},记录优惠券核销表:{}", i, i1, i2);
                                                    throw new CustomException("核销失败");
                                                }
                                            } else {
                                                throw new CustomException(CancelCodeMsg.SITE_AND_PERSONNEL_ARE_INCONSISTENT.getMessage());
                                            }
                                        } else {
                                            throw new CustomException(CancelCodeMsg.THIS_COUPON_IS_INVALID.getMessage());
                                        }
                                    } else {
                                        throw new CustomException(CancelCodeMsg.NOT_CERTIFICATE.getMessage());
                                    }
                                } else {
                                    throw new CustomException(CancelCodeMsg.COUPON_VERIFICATION_USED.getMessage());
                                }
                            } else {
                                throw new CustomException(CancelCodeMsg.ERROR_COUPON_DATE.getMessage());
                            }
                        } else {
                            throw new CustomException(CancelCodeMsg.THERE_IS_NO_SUCH_WRITE_OFF.getMessage());
                        }
                    } else {
                        throw new CustomException(CancelCodeMsg.ACCOUNT_DISABLE.getMessage());
                    }
                } else {
                    throw new CustomException(CancelCodeMsg.NOT_COUPON_VERIFICATION_USER.getMessage());
                }
                break;
            //洗车券
            case "4":
                return checkCoupon(couponUser,sysUser,ccd);
            default:
                throw new IllegalStateException("Unexpected value: " + couponUser.getCancelCouponTemplateInfo().getCouponType());
        }
        return 0;
    }

    public Integer checkCoupon(CancelCouponUser couponUser, SysUser sysUser, CancelCouponDto ccd)throws Exception{
        log.info("查询油品信息入参：{}", ccd.getStationId());
        List<Oil> listByStationId = oilService.getListByStationId(Long.valueOf(ccd.getStationId()));
        String oilType = null;
/*        if (CollectionUtil.isNotEmpty(listByStationId)){
            for (Oil oil : listByStationId) {
                //支付项目也要改 newCarWashCouponDestroy
                if (oil.getOilClass().equals("服务")){
                    oilType = "洗车";
                    break;
                }
            }
        }*/

        String enterpriseId = String.valueOf(sysUser.getEnterpriseId());
        String couponUserEnterpriseId = couponUser.getEnterpriseId().toString();
        if (!enterpriseId.equals(couponUserEnterpriseId)) {
            throw new CustomException(CancelCodeMsg.SITE_AND_PERSONNEL_ARE_INCONSISTENT.getMessage());
        }
        String couponStaNames = couponUser.getCouponStaNames();
        Station station = iStationService.selectStationById(sysUser.getStationId());
        String stationName = station.getStationName();
        List<String> nameList = Arrays.asList(couponStaNames.split(","));

        if (!nameList.contains(stationName)) {
            throw new CustomException(CancelCodeMsg.CAN_BE_HERE.getMessage());
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (simpleDateFormat.parse(couponUser.getCouponEffectiveTime()).after(new Date())) {

            //状态
            if ("0".equals(couponUser.getCouponIsUsed())) {

             /*   if (null == oilType ) {
                    throw new CustomException(CancelCodeMsg.NOT_A_CAR_WASH.getMessage());
                }*/
                CancelCouponTemplate couponTemplateInfo = couponUser.getCancelCouponTemplateInfo();

                String effectiveTimeType = couponTemplateInfo.getEffectiveTimeType();
                if (null != effectiveTimeType && effectiveTimeType.equals("1")) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String effectiveTimeEnd = sdf.format(couponTemplateInfo.getEffectiveTimeEnd());
                    String effectiveTimeStart = sdf.format(couponTemplateInfo.getEffectiveTimeStart());
                    if (simpleDateFormat.parse(effectiveTimeStart).after(new Date())) {
                        throw new CustomException(CancelCodeMsg.TIME_IS_NOT_UP.getMessage());
                    }

                }

                //判断是否洗车券及状态
                if (ObjectUtils.isNotEmpty(couponTemplateInfo) &&  "1".equals(couponTemplateInfo.getCouponTemplateStatus())) {
                    if (null == couponTemplateInfo.getVerification() || Arrays.asList(couponTemplateInfo.getVerification().split(",")).contains(sysUser.getStationId())) {
                        //更新用户优惠券信息
                        int i = couponInfoService.updateCouponUser(CancelCouponUser.builder().couponNo(ccd.getCouponNo()).verificationTime(new Date()).couponIsUsed("1").verificationUserAccount(sysUser.getUserName()).verificationUserPhone(sysUser.getPhonenumber()).build());
                        //更新优惠券使用模板数量
                        int i1 = couponInfoService.updateCouponTemplate(CancelCouponTemplate.builder().couponTemplateId(couponTemplateInfo.getCouponTemplateId()).useCouponNum(couponTemplateInfo.getUseCouponNum() + 1).build());
                        //记录在优惠券核销表
                        Integer i2 = addCancelCouponRecord(couponUser, ccd);
                        if (i != 1 || i1 != 1 || i2 != 1) {
                            log.error("更新用户优惠券信息:{},更新优惠券使用模板数量:{},记录优惠券核销表:{}", i, i1, i2);
                            throw new CustomException("核销失败");
                        }

                        //核销完洗车券打开开关
                        StationDeviceManage stationDeviceManage = stationDeviceManageMapper.selectDeviceNoByStationId(sysUser.getStationId().intValue(), "9");
                        if(null!=stationDeviceManage){
                            Boolean aBoolean = stringRedisTemplate.hasKey(Constants.DEVICE_RELAY_ID + stationDeviceManage.getDeviceNo());
                            if(aBoolean!=null && aBoolean){
                                throw new CustomException("设备正在运行中");
                            }
                            EquipmentMessageDTO message = new EquipmentMessageDTO();
                            message.setCmd("data");
                            message.setData(stationDeviceManage.getDurationConversion());
                            providerClient.publish(stationDeviceManage.getDeviceNo()+ ApiConst.MQTT_PRODUCER_TOPIC, JSON.toJSONString(message));
                            stringRedisTemplate.opsForValue().set(Constants.DEVICE_RELAY_ID+stationDeviceManage.getDeviceNo(), "",stationDeviceManage.getDuration(), TimeUnit.MINUTES);
                        }
                        return 1;
                    }
                }
                throw new CustomException(CancelCodeMsg.THIS_COUPON_IS_INVALID.getMessage());
            }
            throw new CustomException(CancelCodeMsg.NO_CAR_WASH_TICKET.getMessage());
        }
        throw new CustomException(CancelCodeMsg.TIME_IS_NOT_UP.getMessage());
    }

    //优惠券核销记录表
    private Integer addCancelCouponRecord(CancelCouponUser couponUser, CancelCouponDto ccd) {

        CouponWriteOffRecords couponWriteOffRecords = new CouponWriteOffRecords();
        couponWriteOffRecords.setCouponNo(couponUser.getCouponNo());
        couponWriteOffRecords.setAmt(couponUser.getCancelCouponTemplateInfo().getCouponAmt());
        couponWriteOffRecords.setCreatedDate(new Date());
        couponWriteOffRecords.setEnterpriseId(Long.valueOf(couponUser.getEnterpriseId()));
        couponWriteOffRecords.setStationId(Long.valueOf(ccd.getStationId()));
        couponWriteOffRecords.setCouponType(Integer.valueOf(couponUser.getCancelCouponTemplateInfo().getCouponType()));
        couponWriteOffRecords.setWriteOffPersonnelId(Integer.valueOf(ccd.getOilPersonnelId()));
        return couponWriteOffRecordsMapper.insert(couponWriteOffRecords);
    }

    private Integer cancelGoods(IntegralOrder integralOrder, SysUser sysUser, CancelCouponDto ccd){

        Long stationId = integralOrder.getStationId();

        if (!stationId.equals(sysUser.getStationId())) {
            throw new CustomException("该商品不能在此站点核销");
        }
        //更改订单状态
        integralOrder.setWriteOffStatus(1);
        integralOrder.setWriteOffTime(new Date());
        integralOrderService.updateIntegralOrder(integralOrder);
        String enterpriseId = String.valueOf(sysUser.getEnterpriseId());
        //记录核销
        PointsMerchandiseWriteOffRecord build = PointsMerchandiseWriteOffRecord.builder()
                .integralOrderNo(integralOrder.getIntegralOrderNo())
                .mobilePhone(integralOrder.getMobilePhone())
                .EliminationNumber(integralOrder.getExchangeNum())
                .stationId(sysUser.getStationId())
                .enterpriseId(Long.valueOf(enterpriseId))
                .createdDate(new Date())
                .build();
      return   pointsMerchandiseWriteOffRecordService.addCancelGoods(build);
    }
}
